package org.outlook.common.date;


import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.time.DurationFormatUtils;
import org.outlook.common.date.IntervalTime.TimeType;

public class OutlookDateFormat extends DateFormat {
	
	private static final long serialVersionUID = 1L;
	
	private String lang;
	
	public OutlookDateFormat(String lang) {
		if(lang == null)
			this.lang = "en";
		this.lang = lang;
	}
	
	@Override
	public StringBuffer format(Date date, StringBuffer toAppendTo,
			FieldPosition fieldPosition) {
		IntervalTime it = new IntervalTime();
		Calendar today = Calendar.getInstance();
		Calendar converDate = Calendar.getInstance();
		converDate.setTime(date);
		String formatDuration = DurationFormatUtils.formatPeriod(converDate.getTimeInMillis(), today.getTimeInMillis(), "y M d H m s");
		String[] split = formatDuration.split(" ");
		for (int i = 0; i < 6; i++) {
			if (Integer.parseInt(split[i]) != 0) {
				it.setInterval(Integer.parseInt(split[i]));
				it.setLang(lang);
				it.setAsc(today.before(converDate));
				if(lang.equalsIgnoreCase("zh"))
					it.setType(TimeType.value(i+6));
				it.setType(TimeType.value(i));
				break;
			}
		}
		return new StringBuffer(it.toString());
	}

	@Override
	public Date parse(String source, ParsePosition pos) {
		IntervalTime it = converToIntervalTime(source);
		int interval = it.getInterval();
		TimeType type = it.getType();
		Calendar today = Calendar.getInstance();
		
		long intervalNum = TimeType.getNumByType(type);
		if(it.isAsc())
			interval *= -1;
		intervalNum *= interval;
		return new Date(today.getTimeInMillis() + intervalNum);
	}
	
	@Override
	public Date parse(String source) throws ParseException
    {
		IntervalTime it = converToIntervalTime(source);
		int interval = it.getInterval();
		TimeType type = it.getType();
		Calendar today = Calendar.getInstance();
		
		long intervalNum = TimeType.getNumByType(type);
		if(it.isAsc())
			interval *= -1;
		intervalNum *= interval;
		return new Date(today.getTimeInMillis() + intervalNum);
    }

	private IntervalTime converToIntervalTime(String source) {
		String lang = getLang(source);
		boolean asc = isAsc(source, lang);
		int interval = getInteger(source);
		boolean space = getSpace(source);
		TimeType type = getType(source);
		return new IntervalTime(asc, interval, lang, space, type);
		
	}

	private boolean getSpace(String source) {
		if(source.indexOf(" ")!= -1)
			return true;
		return false;
	}

	private TimeType getType(String source) {
		TimeType[] tt = TimeType.values();
		for(int i=0; i<tt.length; i++)
			if(source.indexOf(tt[i].toString()) != -1)
				return tt[i];
		return null;
	}

	private Integer getInteger(String source) {
		String regex = "(\\d+?)";
		String s = source.replaceAll(regex, "");
		int i = source.indexOf(s);
		if(i > -1)
			return Integer.parseInt(source.substring(0, i));
		return 0;
	}

	private boolean isAsc(String source, String lang) {
		if("en".equals(lang)) {
			if(source.endsWith(IntervalTime.AFTER))
				return true;
		} else {
			if(source.endsWith(IntervalTime.AFTER_ZH))
				return true;
		}
		return false;
	}

	private String getLang(String source) {
		for(int i=0;i<source.length(); i++) {
			int ii=(int)source.charAt(i);
			if(ii<=0  ||ii>=126){
				return "zh";
			}
		}
		return "en";
	}

}
